package com.hwq.sql.tool.model;

import com.hwq.sql.tool.utils.StrUtil;
import com.sun.deploy.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ExcelTemp {

    private final Config config;

    public ExcelTemp(Config config) {
        this.config = config;
    }

    /**
     * 读取模板的 sheet 页，获取有多少表
     */
    public List<Table> getTables() {
        List<Table> tables = new ArrayList<>();
        try (
                XSSFWorkbook wb = new XSSFWorkbook(config.getRootPath() + config.getTempName())
        ) {
            for (int i = 2; i < wb.getNumberOfSheets(); i++) {
                Table table = new Table();
                XSSFSheet sheet = wb.getSheetAt(i);
                String tableName = sheet.getSheetName();
                if (StrUtil.isBlank(tableName)) {
                    continue;
                }
                table.setName(tableName);
                table.setFieldList(this.getFields(sheet));
                analyzeInitField(table);
                analyzeAfterField(table);
                tables.add(table);
            }
            return tables;
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 读取单个 sheet 页中的行，获取表中有多少字段
     */
    private List<Field> getFields(XSSFSheet sheet) {
        List<Field> fieldList = new ArrayList<>();
        for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
            XSSFRow row = sheet.getRow(i);
            XSSFCell cell = row.getCell(0);
            String value = cell.getStringCellValue();
            if (StrUtil.isBlank(value)) {
                continue;
            }
            Field field = new Field(row, config);
            fieldList.add(field);
        }
        return fieldList;
    }

    /**
     * 解析表初始字段，拆分字段获取完整的表对象
     */
    private void analyzeInitField(Table table) {
        List<Field> initField = table.getFieldList().stream().filter(item -> "初始".equals(item.getFieldType())).collect(Collectors.toList());
        List<Field> pkList = new ArrayList<>();
        Map<String, Field> inxMap = new HashMap<>();
        Map<String, List<Field>> uqMap = new HashMap<>();
        for (Field field : initField) {
            if (field.getPk()) {
                pkList.add(field);
            }
            String inx = field.getIndex();
            if (StrUtil.isNotBlank(inx)) {
                inx = table.getName() + "_INX_" + inx;
                inxMap.put(inx, field);
            }
            String uq = field.getUq();
            if (StrUtil.isNotBlank(uq)) {
                uq = table.getName() + "_UQ_" + uq;
                List<Field> list = uqMap.get(uq);
                if (CollectionUtils.isEmpty(list)) {
                    list = new ArrayList<>();
                    uqMap.put(uq, list);
                }
                list.add(field);
            }
        }
        table.setInitFiled(initField);
        table.setPkList(pkList);
        table.setInxMap(inxMap);
        table.setUqMap(uqMap);
    }

    /**
     * 解析表后续添加的字段，拆分字段获取完整的表对象
     */
    private void analyzeAfterField(Table table) {
        List<Field> list = table.getFieldList().stream().filter(item -> !"初始".equals(item.getFieldType())).collect(Collectors.toList());
        List<Field> addList = new ArrayList<>();
        List<Field> repList = new ArrayList<>();
        Map<String, Field> addInxMap = new HashMap<>();
        Map<String, Field> repInxMap = new HashMap<>();
        Map<String, List<Field>> addUqMap = new HashMap<>();
        Map<String, List<Field>> repUqMap = new HashMap<>();
        for (Field field : list) {
            if ("新增".equals(field.getFieldType())) {
                addList.add(field);
            } else if ("替换".equals(field.getFieldType())) {
                repList.add(field);
            }
            String inx = field.getIndex();
            if (StrUtil.isNotBlank(inx)) {
                inx = table.getName() + "_INX_" + inx;
                Field inxField = table.getInxMap().get(inx);
                if (inxField == null) {
                    addInxMap.put(inx, field);
                } else {
                    repInxMap.put(inx, field);
                }
            }
            String uq = field.getUq();
            if (StrUtil.isNotBlank(uq)) {
                uq = table.getName() + "_UQ_" + uq;
                List<Field> uqList = table.getUqMap().get(uq);
                List<Field> newUqList = new ArrayList<>();
                if (CollectionUtils.isEmpty(uqList)) {
                    newUqList.add(field);
                    addUqMap.put(uq, newUqList);
                } else {
                    newUqList.addAll(uqList);
                    newUqList.add(field);
                    if (field.getRemove()) {
                        newUqList = newUqList.stream().filter(item -> !item.getName().equals(field.getName())).collect(Collectors.toList());
                    }
                    repUqMap.put(uq, newUqList);
                }
            }
        }
        table.setAddList(addList);
        table.setRepList(repList);
        table.setAddInxMap(addInxMap);
        table.setRepInxMap(repInxMap);
        table.setAddUqMap(addUqMap);
        table.setRepUqMap(repUqMap);
    }

}
